package com.testclock.erebus.testbleclock;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;

import com.clj.fastble.BleManager;
import com.clj.fastble.conn.BleCharacterCallback;
import com.clj.fastble.conn.BleGattCallback;
import com.clj.fastble.data.ScanResult;
import com.clj.fastble.exception.BleException;

public class OpenActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "OpenActivity";
    BleManager bleManager;
    BleCharacterCallback write, notify;
    private byte[] token = new byte[4];
    private boolean isAuto = false;
    private TextView deviceName;
    private TextView deviceMac;
    private TextView deviceBattery;
    private TextView deviceVersion;
    private TextView deviceCz;
    private TextView deviceStatus;
    private TextView openCount;
    byte[] gettoken = {0x06, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    private int count = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_open);
        bleManager = ((MyApplication) getApplication()).getBleManager();

        write = new BleCharacterCallback() {
            @Override
            public void onSuccess(BluetoothGattCharacteristic characteristic) {
                Log.d(TAG, "write onSuccess");
            }

            @Override
            public void onFailure(BleException exception) {
                Log.d(TAG, "write onFailure" + exception.getDescription());
            }
        };
        notify = new BleCharacterCallback() {
            @Override
            public void onSuccess(final BluetoothGattCharacteristic characteristic) {
                Log.d(TAG, "notify onSuccess");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        parseData(characteristic.getValue());
                    }
                });
            }

            @Override
            public void onFailure(BleException exception) {
                Log.d(TAG, "notify onFailure");
            }
        };
        initView();
    }

    private void initView() {
        ScanResult result = getIntent().getParcelableExtra("result");
        deviceName = (TextView) findViewById(R.id.tv_name);
        deviceMac = (TextView) findViewById(R.id.tv_address);
        deviceBattery = (TextView) findViewById(R.id.tv_battery);
        deviceVersion = (TextView) findViewById(R.id.tv_version);
        deviceCz = (TextView) findViewById(R.id.tv_cz);
        deviceStatus = (TextView) findViewById(R.id.tv_status);
        openCount = (TextView) findViewById(R.id.open_count);
        findViewById(R.id.bt_open).setOnClickListener(this);
        findViewById(R.id.bt_close).setOnClickListener(this);
        findViewById(R.id.bt_status).setOnClickListener(this);
        findViewById(R.id.bt_update_password).setOnClickListener(this);
        ((CheckBox) findViewById(R.id.bt_auto)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                isAuto = isChecked;
            }
        });
        BluetoothDevice device = result.getDevice();
        String name = device.getName();
        String address = device.getAddress();
        if (!TextUtils.isEmpty(name)) {
            deviceName.setText(name);
        }
        if (!TextUtils.isEmpty(address)) {
            deviceMac.setText(address);
        }
        bleManager.connectDevice(result, false, new BleGattCallback() {
            @Override
            public void onNotFoundDevice() {
                setStatus("未找到设备");
            }

            @Override
            public void onFoundDevice(ScanResult scanResult) {

            }

            @Override
            public void onConnectSuccess(BluetoothGatt gatt, int status) {
                setStatus("连接成功");
                gatt.discoverServices();
            }

            @Override
            public void onConnectFailure(BleException exception) {
                finish();
            }

            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                Log.d(TAG, "onServicesDiscovered");
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    //获取服务的对象并判断是否为空
                    BluetoothGattService service = gatt.getService(SampleGattAttributes.bltServerUUID);
                    if (null == service) return;
                    //获取写入特征值和通知特征值的对象并判断是否为空
                    BluetoothGattCharacteristic read_characteristic = service.getCharacteristic(SampleGattAttributes.readDataUUID);
                    BluetoothGattCharacteristic write_characteristic = service.getCharacteristic(SampleGattAttributes.writeDataUUID);
                    if (null == read_characteristic || null == write_characteristic) return;
                    //开启通知属性
                    int properties = read_characteristic.getProperties();
                    if ((properties | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                        notifyMsg();
                        sendMsg(0, 1000);
                    }

                } else {
                    Log.w(TAG, "onServicesDiscovered received: " + status);
                }
            }
        });
    }

    private void notifyMsg() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                bleManager.notify(SampleGattAttributes.bltServerUUID.toString(), SampleGattAttributes.readDataUUID.toString(), notify);

            }
        });
    }

    private void setStatus(final String status) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                deviceStatus.setText(status);
            }
        });

    }

    @Override
    public void onClick(View v) {

        switch (v.getId()) {
            case R.id.bt_open://开锁
                sendMsg(2, 0);
                break;
            case R.id.bt_status://获取锁状态
                sendMsg(4, 0);

                break;
            case R.id.bt_close://复位
                sendMsg(5, 0);
                break;
            case R.id.bt_update_password://修改密码

                sendMsg(6, 0);
                break;
        }
    }

    @Override
    protected void onDestroy() {
        bleManager.closeBluetoothGatt();
        super.onDestroy();
    }

    /**
     * 解析锁反馈的指令
     *
     * @param values 反馈数据
     */
    private void parseData(byte[] values) {
        byte[] x = new byte[16];
        System.arraycopy(values, 0, x, 0, 16);
        byte[] decrypt = BluetoothLeService.Decrypt(x, SampleGattAttributes.key);
        String decryptString = HexUtils.bytesToHexString(decrypt).toUpperCase();
        Log.e(TAG, "value:" + decryptString);
        if (decryptString.startsWith("0602")) {//token
            if (decrypt != null && decrypt.length == 16) {
                if (decrypt[0] == 0x06 && decrypt[1] == 0x02) {
                    token[0] = decrypt[3];
                    token[1] = decrypt[4];
                    token[2] = decrypt[5];
                    token[3] = decrypt[6];

                    deviceVersion.setText("当前版本：" + Integer.parseInt(decryptString.substring(16, 18), 16) + "." + Integer.parseInt(decryptString.substring(18, 20), 16));
                    sendMsg(1, 1000);
                }
            }
            sendMsg(1, 0);
        } else if (decryptString.startsWith("0202")) {//电量

            if (decryptString.startsWith("020201ff")) {
                deviceCz.setText("获取电量失败");
            } else {
                String battery = decryptString.substring(6, 8);
                deviceBattery.setText("当前电量：" + Integer.parseInt(battery, 16));
            }
        } else if (decryptString.startsWith("0502")) {//开锁
            if (decryptString.startsWith("05020101")) {
                deviceCz.setText("开锁失败");
            } else {
                count++;
                deviceCz.setText("开锁成功");
                openCount.setText("开锁次数：" + count);
            }
        } else if (decryptString.startsWith("050F")) {//锁状态
            if (decryptString.startsWith("050F0101")) {
                deviceCz.setText("当前操作：锁已关闭");
            } else {
                deviceCz.setText("当前操作：锁已开启");
            }
        } else if (decryptString.startsWith("050D")) {//复位
            if (decryptString.startsWith("050D0101")) {
                deviceCz.setText("当前操作：复位失败");
            } else {
                deviceCz.setText("当前操作：复位成功");
            }
        } else if (decryptString.startsWith("0508")) {//上锁
            if (decryptString.startsWith("05080101")) {
                deviceCz.setText("当前操作：上锁失败");
            } else {
                deviceCz.setText("当前操作：上锁成功");
                if (isAuto) {
                    sendMsg(2, 2000);
                }

            }
        } else if (decryptString.startsWith("0505")) {
            if (decryptString.startsWith("05050101")) {
                deviceCz.setText("当前操作：修改密码失败");
            } else {
                deviceCz.setText("当前操作：修改密码成功");
            }
        } else if (decryptString.startsWith("CB0503")) {
            sendMsg(3, 0);
        }
    }

    private void sendMsg(final int what, final long delay) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                byte[] data = null;
                switch (what) {
                    case 0:
                        data = gettoken;
                        break;
                    case 1://获取电量
                        data = new byte[]{0x02, 0x01, 0x01, 0x01, token[0], token[1], token[2], token[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
                        break;
                    case 2://开锁
                        data = new byte[]{0x05, 0x01, 0x06, SampleGattAttributes.password[0], SampleGattAttributes.password[1], SampleGattAttributes.password[2], SampleGattAttributes.password[3], SampleGattAttributes.password[4], SampleGattAttributes.password[5], token[0], token[1], token[2], token[3], 0x00, 0x00, 0x00};
                        break;
                    case 3://
                        data = new byte[]{0x05, 0x04, 0x06, SampleGattAttributes.password[0], SampleGattAttributes.password[1], SampleGattAttributes.password[2], SampleGattAttributes.password[3], SampleGattAttributes.password[4], SampleGattAttributes.password[5], token[0], token[1], token[2], token[3], 0x00, 0x00, 0x00};
                        break;
                    case 4://锁状态
                        data = new byte[]{0x05, 0x0E, 0x01, 0X01, token[0], token[1], token[2], token[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
                        break;
                    case 5://复位
                        data = new byte[]{0x05, 0x0c, 0x01, 0x01, token[0], token[1], token[2], token[3], 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
                        break;
                    case 6://修改密码
                        data = new byte[]{0x05, 0x03, 0x06, SampleGattAttributes.password[0], SampleGattAttributes.password[1], SampleGattAttributes.password[2], SampleGattAttributes.password[3], SampleGattAttributes.password[4], SampleGattAttributes.password[5], token[0], token[1], token[2], token[3], 0x00, 0x00, 0x00};
                        break;
                }
                final byte[] finalData = data;
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        bleManager.writeDevice(SampleGattAttributes.bltServerUUID.toString(), SampleGattAttributes.writeDataUUID.toString(), BluetoothLeService.Encrypt(finalData, SampleGattAttributes.key), write);
                    }
                }, delay);
            }
        });
    }
}
